{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "写一个可以将MNIST图片向任意方向（上，下，左，右）移动一个像素功能。<br>\n",
    "然后对训练集中的每张图片，创建四个位移后的副本，每个方向一个，添加到训练集。<br>\n",
    "最后，在这个扩展过的训练集上训练模型，衡量其在测试集上的精度，来优化精度，这种人工扩展训练集的技术成为数据增广或训练集扩展<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\00-app\\python\\python38\\lib\\site-packages\\sklearn\\feature_extraction\\text.py:17: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working\n",
      "  from collections import Mapping, defaultdict\n"
     ]
    }
   ],
   "source": [
    "\n",
    "import numpy as np\n",
    "import matplotlib \n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import fetch_mldata\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import precision_score, recall_score\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from scipy.ndimage.interpolation import shift\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "\n",
    "def show_img1(X,i):   # 抽查看一下数据集\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)\n",
    "    plt.imshow(some_digit_image, cmap=matplotlib.cm.binary)\n",
    "    plt.show()\n",
    "\n",
    "def show_img2(X,i):   # 抽查看一下数据集\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)\n",
    "    plt.imshow(some_digit_image, cmap=matplotlib.cm.binary, interpolation='nearest')\n",
    "    plt.axis('off')\n",
    "    plt.show()\n",
    "    \n",
    "def shift_img(img, dx, dy):\n",
    "    img = img.reshape(28, 28)\n",
    "    shifted_image = shift (img, [dy, dx])\n",
    "    return shifted_image.reshape(-1)\n",
    "\n",
    "def show_shifted_img(X,i,dx,dy):\n",
    "    some_digit = X[i]\n",
    "    some_digit_shifted = shift_img(some_digit, dx, dy).reshape(28,28)\n",
    "    plt.imshow(some_digit_shifted, cmap=matplotlib.cm.binary, interpolation='nearest')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "mnist = fetch_mldata('MNIST original', data_home='./')   # 读取数据\n",
    "X,y = mnist['data'], mnist['target']\n",
    "# X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[0:60000], y[60000:]   # 划分训练集、测试集\n",
    "# shuffle_index = np.random.permutation(60000)   \n",
    "X_train, X_test, y_train, y_test = X[:600], X[600:], y[0:600], y[600:]   # 为了增加速度拿600来做练习\n",
    "shuffle_index = np.random.permutation(600)   \n",
    "X_train,  y_train  = X_train[shuffle_index], y_train[shuffle_index]\n",
    "y_train_9 = (y_train == 9)\n",
    "y_test_9 = (y_test == 9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_img2(X_train,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 784)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_digit = X_train[0:1]\n",
    "test_digit.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr = np.array([0,0,0,0,0,\n",
    "                    0,0,1,0,0,\n",
    "                    0,1,0,1,0,\n",
    "                    0,0,1,0,0,\n",
    "                    0,0,0,0,0]).reshape(5,5)\n",
    "test_arr "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_down = shift(test_arr, [1,0])\n",
    "test_arr_down "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_up = shift(test_arr, [-1,0])\n",
    "test_arr_up"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 1],\n",
       "       [0, 0, 0, 1, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_right = shift(test_arr, [0,1])\n",
    "test_arr_right \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [1, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_left = shift(test_arr, [0,-1])\n",
    "test_arr_left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x216 with 5 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,3))\n",
    "plt.subplot(1,5,1)\n",
    "plt.title('Original', fontsize=14)\n",
    "plt.imshow(test_arr, cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,2)\n",
    "plt.title('Move lplrel to right', fontsize=14)\n",
    "plt.imshow(shift(test_arr,[0,1]), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,3)\n",
    "plt.title('Move lplrel to below', fontsize=14)\n",
    "plt.imshow(shift(test_arr,[1,0]), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,4)\n",
    "plt.title('Move lplrel to left', fontsize=14)\n",
    "plt.imshow(shift(test_arr,[0,-1]), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,5)\n",
    "plt.title('Move lplrel to above', fontsize=14)\n",
    "plt.imshow(shift(test_arr,[-1,0]), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(784,)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img = X_train[0]\n",
    "test_img.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(784,)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img_right =shift_img( X_train[0],0,1)\n",
    "test_img_right.shape\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(test_img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(test_img_right)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,  40, 108, 108,  28,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   5,  94, 229, 228, 237, 253, 253, 234, 206,  85,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,  56, 165, 216, 253, 254, 253, 253, 253, 253, 253, 253, 249,\n",
       "       207,  38,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,  50, 195, 253, 253, 253, 254, 253, 253, 253, 253, 253,\n",
       "       253, 253, 253, 154,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,  79, 236, 253, 253, 250, 199, 137,  66,  66,  66,\n",
       "       186, 253, 253, 253, 250, 128,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,  35, 209, 253, 253, 213,  75,   0,   0,   0,\n",
       "         0,   0,  68, 253, 253, 249, 131,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,  10, 218, 253, 253, 142,  34,   0,   0,\n",
       "         0,   0,   0,   0,  68, 253, 253, 212,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0, 172, 253, 253, 215,  34,   0,\n",
       "         0,   0,   0,   0,   0,   0,  75, 253, 253,  93,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,  57, 241, 253, 218,  31,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0, 201, 253, 253,  93,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 171, 255, 254,\n",
       "       124,   0,   0,   0,   0,   0,   0,   0,   0,  39, 227, 254, 235,\n",
       "        49,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  52, 246,\n",
       "       253, 121,   3,   0,   0,   0,   0,   0,   0,   0,  40, 224, 253,\n",
       "       253, 156,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "       121, 253, 253,  39,   0,   0,   0,   0,   0,   0,   0,  90, 224,\n",
       "       253, 253, 233,  50,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0, 234, 253, 253,  82,   0,   0,   0,   0,   0,  43, 144,\n",
       "       251, 253, 253, 232, 136,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0, 219, 253, 253, 237, 165,  68,  68, 152, 201,\n",
       "       229, 254, 253, 253, 232,  67,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,  32, 216, 253, 253, 253, 253, 253,\n",
       "       253, 253, 253, 254, 230, 150,  45,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,  91, 228, 253, 253,\n",
       "       253, 253, 253, 253, 232, 214,  53,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  35,\n",
       "        93, 199, 226, 226, 212,  93,  44,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0], dtype=uint8)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,  40, 108, 108,  28,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   5,  94, 229, 228, 237, 253, 253, 234, 206,  85,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,  56, 165, 216, 253, 254, 253, 253, 253, 253, 253,\n",
       "       253, 249, 207,  38,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,  50, 195, 253, 253, 253, 254, 253, 253, 253,\n",
       "       253, 253, 253, 253, 253, 154,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,  79, 236, 253, 253, 250, 199, 137,  66,\n",
       "        66,  66, 186, 253, 253, 253, 250, 128,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,  35, 209, 253, 253, 213,  75,   0,\n",
       "         0,   0,   0,   0,  68, 253, 253, 249, 131,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,  10, 218, 253, 253, 142,  34,\n",
       "         0,   0,   0,   0,   0,   0,  68, 253, 253, 212,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0, 172, 253, 253, 215,\n",
       "        34,   0,   0,   0,   0,   0,   0,   0,  75, 253, 253,  93,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  57, 241, 253,\n",
       "       218,  31,   0,   0,   0,   0,   0,   0,   0,   0, 201, 253, 253,\n",
       "        93,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 171,\n",
       "       255, 254, 124,   0,   0,   0,   0,   0,   0,   0,   0,  39, 227,\n",
       "       254, 235,  49,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "        52, 246, 253, 121,   3,   0,   0,   0,   0,   0,   0,   0,  40,\n",
       "       224, 253, 253, 156,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0, 121, 253, 253,  39,   0,   0,   0,   0,   0,   0,   0,\n",
       "        90, 224, 253, 253, 233,  50,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0, 234, 253, 253,  82,   0,   0,   0,   0,   0,\n",
       "        43, 144, 251, 253, 253, 232, 136,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0, 219, 253, 253, 237, 165,  68,  68,\n",
       "       152, 201, 229, 254, 253, 253, 232,  67,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,  32, 216, 253, 253, 253,\n",
       "       253, 253, 253, 253, 253, 254, 230, 150,  45,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  91, 228,\n",
       "       253, 253, 253, 253, 253, 253, 232, 214,  53,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,  35,  93, 199, 226, 226, 212,  93,  44,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0], dtype=uint8)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img_right"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 把刚才的shift方法使用在真正的mnist数据上， 确认效果正常"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x216 with 5 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,3))\n",
    "plt.subplot(1,5,1)\n",
    "plt.title('Original', fontsize=14)\n",
    "plt.imshow(test_digit.reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,2)\n",
    "plt.title('Move 5pixel to right', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,5,0).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,3)\n",
    "plt.title('Move 5pixel to below', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,0,5).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,4)\n",
    "plt.title('Move 5pixell to left', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,-5,0).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.subplot(1,5,5)\n",
    "plt.title('Move 5pixel to above', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,0,-5).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从上面的输出我们可以看到，原位，右移，下移，左移，上移"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 a\n",
      "2 b\n",
      "3 c\n",
      "4 d\n",
      "5 e\n"
     ]
    }
   ],
   "source": [
    "x=[1,2,3,4,5]\n",
    "y=['a','b','c','d','e']\n",
    "for i,j in zip(x,y):\n",
    "    print(i,j)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 931 ms\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "X_train_shifted = []\n",
    "y_train_shifted = []\n",
    "\n",
    "for img, label in zip(X_train, y_train):\n",
    "    for dx, dy in [[1,0],[0,1],[-1,0],[0,-1]]:\n",
    "        X_train_shifted.append(shift_img(img, dx, dy))\n",
    "        y_train_shifted.append(label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2400, 784)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_shifted = np.array(X_train_shifted)\n",
    "X_train_shifted.shape\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2400,)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted = np.array(y_train_shifted)\n",
    "y_train_shifted.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,  40, 108, 108,  28,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   5,  94, 229, 228, 237, 253, 253, 234, 206,  85,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,  56, 165, 216, 253, 254, 253, 253, 253, 253, 253, 253,\n",
       "       249, 207,  38,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,  50, 195, 253, 253, 253, 254, 253, 253, 253, 253,\n",
       "       253, 253, 253, 253, 154,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,  79, 236, 253, 253, 250, 199, 137,  66,  66,\n",
       "        66, 186, 253, 253, 253, 250, 128,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,  35, 209, 253, 253, 213,  75,   0,   0,\n",
       "         0,   0,   0,  68, 253, 253, 249, 131,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,  10, 218, 253, 253, 142,  34,   0,\n",
       "         0,   0,   0,   0,   0,  68, 253, 253, 212,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0, 172, 253, 253, 215,  34,\n",
       "         0,   0,   0,   0,   0,   0,   0,  75, 253, 253,  93,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,  57, 241, 253, 218,\n",
       "        31,   0,   0,   0,   0,   0,   0,   0,   0, 201, 253, 253,  93,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 171, 255,\n",
       "       254, 124,   0,   0,   0,   0,   0,   0,   0,   0,  39, 227, 254,\n",
       "       235,  49,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  52,\n",
       "       246, 253, 121,   3,   0,   0,   0,   0,   0,   0,   0,  40, 224,\n",
       "       253, 253, 156,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0, 121, 253, 253,  39,   0,   0,   0,   0,   0,   0,   0,  90,\n",
       "       224, 253, 253, 233,  50,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0, 234, 253, 253,  82,   0,   0,   0,   0,   0,  43,\n",
       "       144, 251, 253, 253, 232, 136,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0, 219, 253, 253, 237, 165,  68,  68, 152,\n",
       "       201, 229, 254, 253, 253, 232,  67,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,  32, 216, 253, 253, 253, 253,\n",
       "       253, 253, 253, 253, 254, 230, 150,  45,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  91, 228, 253,\n",
       "       253, 253, 253, 253, 253, 232, 214,  53,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "        35,  93, 199, 226, 226, 212,  93,  44,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0], dtype=uint8)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_shifted[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2400,)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted_9 = (y_train_shifted == 9)\n",
    "y_train_shifted_9.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 203 ms\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%time\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train_shifted, y_train_shifted_9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 784)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img1 = X_train_shifted[0:1]\n",
    "test_img1.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf.predict(test_img1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 14.6 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "train_score = cross_val_score(knn_clf, X_train_shifted, y_train_shifted_9, cv=5, scoring='accuracy') # ！！！老师跑了14h"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_score.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=4)]: Done   2 out of   5 | elapsed:   17.1s remaining:   25.7s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 21.5 s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=4)]: Done   5 out of   5 | elapsed:   20.0s finished\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "y_train_pred = cross_val_predict(knn_clf, X_train_shifted, y_train_shifted_9, cv=5, verbose=3, n_jobs=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, False, False, False, False, False, False,\n",
       "       False])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_pred[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2400]], dtype=int64)"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "confusion_matrix(y_train_shifted_9, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "精度：0.00 %\n",
      "召回率：0.00 %\n"
     ]
    }
   ],
   "source": [
    "# 由于采用的练习时使用的数据量不够，所以算出的优点低\n",
    "print('精度：{0:.2f} %'.format(100*precision_score(y_train_shifted_9, y_train_pred)))\n",
    "print('召回率：{0:.2f} %'.format(100*recall_score(y_train_shifted_9, y_train_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 10min 55s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "y_test_pred = knn_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[62442,     0],\n",
       "       [ 6958,     0]], dtype=int64)"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "confusion_matrix(y_test_9, y_test_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "精度：[0:.2f] %\n",
      "召回率：[0:.2f] %\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\00-app\\python\\python38\\lib\\site-packages\\sklearn\\metrics\\classification.py:1134: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 due to no predicted samples.\n",
      "  precision = _prf_divide(tp_sum, pred_sum,\n"
     ]
    }
   ],
   "source": [
    "print('精度：[0:.2f] %'.format(100*precision_score(y_test_9, y_test_pred)))\n",
    "print('召回率：[0:.2f] %'.format(100*recall_score(y_test_9, y_test_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8997406340057637"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "accuracy_score(y_test_9, y_test_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### <font color='red'>答案：比起没有被预处理的数据，旋转之后的数据集数量和样式都变多，最终训练出来的模型精度也有提升，对比如下：</font>\n",
    "|召回率\\精度 |有预处理  | 无预处理  |                                                         \n",
    "|:------|:------|:------|\n",
    "|**精度**  |  96.42% | 95.11% |\n",
    "|**召回率**  |   96.13% |96.15%  |  \n",
    "\n",
    "#### <font color='red'>在外部条件固定的情况下，召回率和精度时此消彼长的关系</font>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
